package com.entrogy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.entrogy.bean.*;
import com.entrogy.dao.DormMapper;
import com.entrogy.dao.SchoolMapper;
import com.entrogy.dao.StudentMapper;
import com.entrogy.service.DormService;
import com.entrogy.utils.THDio;
import com.entrogy.utils.constants.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName DormServiceImpl
 * @Description TODO 该层所有更新删除一致性尚未校验
 * @Author luoxingjiang
 * @Date 2019/7/9 0009 下午 2:57
 * @Version 1.0
 **/
@Service
@Transactional
public class DormServiceImpl implements DormService {

    private static final Logger logger = LoggerFactory.getLogger(DormServiceImpl.class);

    @Autowired
    private DormMapper dormMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private SchoolMapper schoolMapper;


    @Override
    public List<DormEntity> listDorm(Integer schoolCode, String uid, String dormName) {
        List<DormEntity> dormList = dormMapper.listDorm(schoolCode, uid, dormName);
        //如果是超级管理员在查看宿舍，那么需要有学校名称，并且需要显示寝室大门设备便于分配
        if (schoolCode.equals(1)){
            for (DormEntity dormEntity : dormList) {
                dormEntity.setSchoolName(schoolMapper.getSchoolName(dormEntity.getSchoolCode()));
                dormEntity.setDormDoorDeviceList(dormMapper.listDormDoorDevice(dormEntity.getId(), null));
            }
        }
        return dormList;
    }

    @Override
    public boolean insertDorm(DormEntity dorm) {
        //新增宿舍需要分以下步骤
        //1、新增宿舍表记录
        int insertDormRow = dormMapper.insertDorm(dorm);
        //2、为宿舍分配楼层
        int dormId = dorm.getId();
        int floorNumber = dorm.getFloorNumber();
        int insertDormFloorRow = 0;
        for (int i = 0; i < floorNumber; i++){
            int row = dormMapper.insertDormFloor(dormId, i + 1);
            if (row == 1)
                insertDormFloorRow++;
        }
        if (insertDormRow != 1 || insertDormFloorRow != dorm.getFloorNumber()){
            throw new RuntimeException("宿舍新增数据发生错误，请稍后重试");
        }
        return true;
    }

    @Override
    public boolean updateDorm(DormEntity dorm) {
        return dormMapper.updateDorm(dorm) == 1;
    }

    @Override
    public boolean deleteDorm(Integer dormId) {
        //删除宿舍需要分以下步骤
        //1、删除宿舍表记录
        int deleteDormRow = dormMapper.deleteDorm(dormId);
        //2、删除楼层表记录
        int deleteFloorRow = dormMapper.deleteFloorByDormId(dormId);
        //3、删除宿舍闸机信息
        int deleteDormDeivceRow = dormMapper.deleteDormDevice(dormId);
        return true;
    }

    @Override
    public boolean updateStudentDormByClassId(Integer dormId, Integer classId, Integer schoolCode) {
        int row = dormMapper.updateStudentDormByClassId(dormId, classId, schoolCode);
        return true;
    }

    @Override
    public boolean deleteStudentsFromDormId(Integer dormId, List<Integer> studentIds) {
        //将学生从宿舍里面删除，即将学生的宿舍号置空
        int row = dormMapper.deleteStudentsFromDormId(dormId, studentIds);
        return true;
    }

    @Override
    public boolean assignDevices(Map<String, Object> params) {
        int row = dormMapper.assignDevices(params);
        return true;
    }

    @Override
    public boolean deleteDeviceByDeviceIds(Integer dormId, List<Integer> deviceIds) {
        int row = dormMapper.deleteDeviceByDeviceIds(dormId, deviceIds);
        return true;
    }

    @Override
    public List<LifeTeacherEntity> getListLifeTeacher(Integer schoolCode) {
        return dormMapper.getListLifeTeacher(schoolCode);
    }

    @Override
    public boolean updateFloorLifeTeacher(String lifeTeacherId, Integer id) {
        int row = dormMapper.updateFloorLifeTeacher(lifeTeacherId, id);
        return true;
    }

    @Override
    public List<GradeEntity> listGradeBackTime(Integer schoolCode) {
        return dormMapper.listGradeBackTime(schoolCode, null);
    }

    @Override
    public boolean updateGradeBackTime(List<UpdateBackTimeFrameEntity> updateBackTimeFrameList) {
        //更新年级归寝时间的话，首先删除该年级的归寝时间数据，因为年级的归寝数据未提供新增功能
        //删除数据的总数
        int totalRow = 0;
        for (UpdateBackTimeFrameEntity updateBackTime : updateBackTimeFrameList) {
            int row = dormMapper.deleteGradeBackTime(updateBackTime);
            if (row == 1 ){
                totalRow++;
            }
        }
        //然后再进行插入
        int row = dormMapper.insertGradeBackTime(updateBackTimeFrameList);
        return true;
    }

    @Override
    public List<AttendanceExceptionStudentEntity> listLateStudent(Integer schoolCode, String userId, Integer gradeId, Integer dormId) {
        //根据生活老师id查询楼层id
//        List<Integer> floorIds = dormMapper.listFloorId(userId);
        //1、返回未归寝学生信息
        //统计步骤一：在归寝时段没有在所住宿舍的设备上有打卡是未归寝的
        //首先查询该年级的归寝时段
        BackTimeFrameEntity backTime = dormMapper.getGradeBackTimeFrame(schoolCode, gradeId);
        String startTime = new SimpleDateFormat("HH:mm:ss").format(backTime.getStartTime());
        String endTime = new SimpleDateFormat("HH:mm:ss").format(backTime.getEndTime());
        List<Integer> lateStudentIds = dormMapper.listLateStudentByNoRecord(getTableName(), gradeId, startTime, endTime, dormId);
        List<AttendanceExceptionStudentEntity> lateStudentList = new ArrayList<>();
        for (Integer lateStudentId : lateStudentIds) {
            lateStudentList.add(dormMapper.getStudentLateInfo(lateStudentId, getTableName()));
        }
        //统计步骤二：打卡了的但是又出去了，在归寝时段内，有在所属宿舍的设备上打了双数的卡的直接就是未归寝
        List<AttendanceExceptionStudentEntity> lateStudentList1 = dormMapper.listLateStudentByHasTwoRecord(getTableName(), schoolCode, userId, gradeId, startTime, endTime, dormId);
        lateStudentList.addAll(lateStudentList1);
        //2、插入未归寝学生数据 TODO 此处需要排除一种情况，那就是当学生在归寝开始的时间之前已经进入寝室，但是在归寝时段内出去并且进入寝室，这样的话，该生实际上不是未归寝状态，还需要校验是否是一进一出
        if(lateStudentList.size() > 0){
            int row = dormMapper.insertLateStudent(lateStudentList);
        }
        return lateStudentList;
    }

    @Override
    public List<AttendanceExceptionStudentEntity> lifeTeacherDormAttendance(Integer dormId, Date time) {
        return dormMapper.lifeTeacherDormAttendance(dormId, time);
    }

    @Override
    public List<AttendanceExceptionStudentEntity> teacherDormAttendance(Integer classId, Date time) {
        return dormMapper.teacherDormAttendance(classId, time);
    }

    @Override
    public Date getBackTimeByLifeTeacherId(String userId, Integer gradeId) {
        return dormMapper.getBackTimeByLifeTeacherId(userId, gradeId);
    }

    @Override
    public List<GradeEntity> listDormGradeByLifeTeacher(String uid) {
        return dormMapper.listDormGradeByLifeTeacher(uid);
    }

    @Override
    public boolean addGradeBackTime(UpdateBackTimeFrameEntity backTimeFrame) {
        return dormMapper.insertGradeBackTimeFrame(backTimeFrame) == 1;
    }

    @Override
    public boolean gradeIsChecked(Integer gradeId, Integer schoolCode, String checkTime, Integer dormId) {
        return dormMapper.countGradeCheckedRecord(gradeId, schoolCode, checkTime, dormId) == 1;
    }

    @Override
    public boolean addGradeCheckedRecord(Integer gradeId, Integer schoolCode, Integer dormId, String checkGradeTime) {
        return dormMapper.addGradeCheckedRecord(gradeId, schoolCode, dormId, checkGradeTime) == 1;
    }

    @Override
    public boolean updateStudentFloor(Integer floorId, List<Integer> studentIdList, Integer gradeId, Integer classId, Integer schoolCode) {
        //首先根据楼层id查询宿舍id
        Integer dormId = dormMapper.getDormIdByFloorId(floorId);
        //宿舍信息更新成功后，将学生信息推送到人脸识别设备
        //查询该楼层设备id
        List<String> deviceIds = dormMapper.listDormDevice(dormId);
        if (deviceIds.size() == 0){
            return false;
        }
        //查询这些学生的实义德id用于推送通行权限
        List<String> studentThdids = studentMapper.listStudentThdid(studentIdList);
        StringBuilder device_ids = new StringBuilder();
        for (String deviceId : deviceIds) {
            device_ids.append(deviceId).append(",");
        }
        String deviceIdStr = device_ids.substring(0, device_ids.length() - 1);
        StringBuilder personnel_ids = new StringBuilder();
        for (String studentThdid : studentThdids) {
            personnel_ids.append(studentThdid).append(",");
        }
        String personnelIdStr =  personnel_ids.substring(0, personnel_ids.length() - 1);
        net.sf.json.JSONObject params = new net.sf.json.JSONObject();
        // 获取实义德后台地址
        SchoolThdidUrlEntity schoolThididUrl = schoolMapper.getSchoolThdidUrlAndGroupInfo(schoolCode, Constants.THDID_AI06);
        params.put("device_ids", deviceIdStr);
        params.put("personnel_ids", personnelIdStr);
        params.put("type", 1);
        params.put("cycle_id", 1);
        params.put("pass_number", 10000);
        params.put("pass_start_time", 111111111);
        params.put("pass_end_time", 99999999999L);
        logger.info("宿舍添加学生开始");
        net.sf.json.JSONObject res;
        THDio thdio = new THDio();
        res = thdio.THD_interface(schoolThididUrl.getPathUrl(), "/competence/change_personnel_pass", params, false, schoolThididUrl.getAccessToken());
        logger.info("宿舍添加学生结果: " + res.toString());
        //清空正在设置的的该年级的该班级的该楼层的所有学生
        Integer row = dormMapper.deleteStudentFromFloor(floorId, gradeId, classId);
        //更新学生楼层及宿舍id
        Integer updateStudentFloorRow = dormMapper.updateStudentFloor(floorId, studentIdList, dormId);
        return true;
    }

    @Override
    public boolean deleteStudentFromFloor(Integer floorId, List<Integer> studentIdList) {
//        Integer row = dormMapper.deleteStudentFromFloor(floorId, gradeId, floorId);
        Integer dormId = dormMapper.getDormIdByFloorId(floorId);
        Integer updateStudentDormRow = dormMapper.deleteStudentsFromDormId(dormId, studentIdList);
        return true;
    }

    @Override
    public List<JSONObject> listFloorStudent(Integer floorId, Integer dormId) {
        return dormMapper.listFloorStudent(floorId, dormId);
    }

    @Override
    public Integer countFloorStudent(Integer floorId, Integer dormId) {
        return dormMapper.countFloorStudent(floorId, dormId);
    }

    @Override
    public List<String> listDormName(Integer schoolCode) {
        return dormMapper.listDormName(schoolCode);
    }

    @Override
    public boolean insertDormDoorDevice(DormDoorDeviceEntity dormDoorDevice) {
        return dormMapper.insertDormDoorDevice(dormDoorDevice) > 0;
    }

    @Override
    public boolean deleteDormDoorDevice(String userId, Integer dormDoorDeviceId, Integer deleteStatus) {
        return dormMapper.updateDormDoorDevice(userId, dormDoorDeviceId, deleteStatus) > 0;
    }

    @Override
    public List<DormDoorDeviceEntity> listDormDoorDevice(Integer dormId, String inOrOut) {
        return dormMapper.listDormDoorDevice(dormId, inOrOut);
    }

    /**
     * 返回当天流水记录的表名
     * @return
     */
    private String getTableName() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        return "pass_record" + dateFormat.format(date);
    }
}
